package com.ruoyi.business.service.wecom.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.business.domain.bo.FollowUserTagKey;
import com.ruoyi.business.domain.vo.wecom.admin.*;
import com.ruoyi.business.domain.wecom.*;
import com.ruoyi.business.mapper.wecom.*;
import com.ruoyi.business.service.wecom.ITbWecomExternalContactCustomerService;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.wecom.WecomCustomerStatusEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 企业微信外部联系人客户表 服务实现类
 * </p>
 *
 * @author
 * @since 2024-01-18
 */
@Service
@Slf4j
public class TbWecomExternalContactCustomerServiceImpl extends ServiceImpl<TbWecomExternalContactCustomerMapper, TbWecomExternalContactCustomer> implements ITbWecomExternalContactCustomerService {

    @Resource
    private TbWecomChatGroupMapper chatGroupMapper;

    @Resource
    private TbWecomChatGroupMemberMapper chatGroupMemberMapper;

    @Resource
    private TbWecomExternalContactCustomerFollowUserMapper customerFollowUserMapper;

    @Resource
    private TbWecomExternalContactFollowUserMapper followUserMapper;

    @Resource
    private TbWecomExternalContactCustomerFollowUserTagMapper customerFollowUserTagMapper;

    @Resource
    private TbWecomTagMapper tbWecomTagMapper;

    @Resource
    private TbWecomTagGroupMapper tbWecomTagGroupMapper;

    @Override
    public TableDataInfo<TbWecomCustomerPageVO> selectSysPageList(Integer gender, Integer type,
                                                                  Integer followStatus, String name,
                                                                  String externalUserid, List<String> tagIds,
                                                                  List<String> userIds, List<String> addWays,
                                                                  Long beginTime, Long endTime,
                                                                  PageQuery pageQuery) {
        long sTime = System.currentTimeMillis();

        try {
            Page<TbWecomCustomerPageVO> page = pageQuery.build();

            // 1. 先查询分页ID（性能关键）
            List<String> externalUserIds = this.baseMapper.selectPageCustomerIds(
                page.offset(), page.getSize(), userIds, tagIds, addWays, name, externalUserid, gender, type, followStatus, beginTime, endTime);

            if (externalUserIds.isEmpty()) {
                log.info("分页查询客户详情：未找到符合条件的记录");
                return TableDataInfo.build(new Page<>(page.getCurrent(), page.getSize(), 0));
            }

            // 2. 查询总数
            Long total = this.baseMapper.selectCountByConditions(userIds, tagIds, addWays, name, externalUserid, gender, type, followStatus, beginTime, endTime);

            // 3. 根据ID批量查询详情
            List<TbWecomCustomerPageVO> records = Collections.emptyList();
            if (!externalUserIds.isEmpty()) {
                records = this.baseMapper.selectCustomerDetailsByIds(externalUserIds);
            }

            // 4. 构建分页结果
            Page<TbWecomCustomerPageVO> resultPage = new Page<>(page.getCurrent(), page.getSize(), total);
            resultPage.setRecords(records);

            long eTime = System.currentTimeMillis();
            log.info("分页查询客户详情完成：总数={}, 当前页记录数={}, 耗时={}ms", total, records.size(), eTime - sTime);

            return TableDataInfo.build(resultPage);

        } catch (Exception e) {
            log.error("分页查询客户详情异常", e);
            throw new RuntimeException("查询客户详情失败", e);
        }
    }

    @Override
    public TableDataInfo<TbWecomCustomerChatGroupPageVO> selectSysChatGroupPageList(List<String> chatIds, Integer type, PageQuery pageQuery) {
        // 构建分页
        Page<TbWecomCustomerChatGroupPageVO> page = pageQuery.build();

        // 1. 分页查询客户基本信息
        IPage<TbWecomCustomerChatGroupPageVO> tbWecomCustomerChatGroupPageVOIPage =
            this.baseMapper.selectWecomCustomerPageListByChatIds(page, chatIds, type);

        List<TbWecomCustomerChatGroupPageVO> customerList = tbWecomCustomerChatGroupPageVOIPage.getRecords();

        if (CollectionUtils.isEmpty(customerList)) {
            return TableDataInfo.build(tbWecomCustomerChatGroupPageVOIPage);
        }

        // 2. 过滤出外部联系人ID
        Set<String> externalUserIds = customerList.stream()
            .map(TbWecomCustomerChatGroupPageVO::getExternalUserid)
            .collect(Collectors.toSet());

        // 3. 批量查询关联数据
        // 3.1 查询客户所在群聊信息
        Map<String, List<CustomerChatGroupVO>> customerChatGroups = getCustomerChatGroups(externalUserIds);

        // 3.2 查询客户所属客服信息
        Map<String, List<CustomerFollowUserVO>> customerFollowUsers = getCustomerFollowUsers(externalUserIds);

        // 4. 组装数据
        assembleCustomerData(customerList, customerChatGroups, customerFollowUsers);

        return TableDataInfo.build(tbWecomCustomerChatGroupPageVOIPage);
    }

    @Override
    public TbWecomCustomerVO sysSelectDetail(String externalUserid) {
        TbWecomExternalContactCustomer tbWecomExternalContactCustomer = this.getOne(Wrappers.lambdaQuery(TbWecomExternalContactCustomer.class)
            .eq(TbWecomExternalContactCustomer::getExternalUserid, externalUserid)
            .last(Constants.MYBATIS_PLUSH_LIMIT_ONE)
        );

        TbWecomCustomerVO tbWecomCustomerVO = new TbWecomCustomerVO();
        BeanUtils.copyProperties(tbWecomExternalContactCustomer, tbWecomCustomerVO);

        // 根据 externalUserid 查询客服相关信息
        List<TbWecomExternalContactCustomerFollowUser> tbWecomExternalContactCustomerFollowUsers = customerFollowUserMapper.selectList(Wrappers.lambdaQuery(TbWecomExternalContactCustomerFollowUser.class)
            .select(TbWecomExternalContactCustomerFollowUser::getExternalUserid,
                TbWecomExternalContactCustomerFollowUser::getUserId,
                TbWecomExternalContactCustomerFollowUser::getRemark,
                TbWecomExternalContactCustomerFollowUser::getDescription,
                TbWecomExternalContactCustomerFollowUser::getAddTime,
                TbWecomExternalContactCustomerFollowUser::getAddWay,
                TbWecomExternalContactCustomerFollowUser::getStatus)
            .eq(TbWecomExternalContactCustomerFollowUser::getExternalUserid, externalUserid)
            .eq(TbWecomExternalContactCustomerFollowUser::getStatus, WecomCustomerStatusEnum.NOT_LOST.getCode()));

        // 获取客服ID
        Set<String> userIds = tbWecomExternalContactCustomerFollowUsers.stream()
            .map(TbWecomExternalContactCustomerFollowUser::getUserId)
            .collect(Collectors.toSet());

        if (userIds.isEmpty()) {
            tbWecomCustomerVO.setCustomerFollowUserDetailVO(new ArrayList<>());
            return tbWecomCustomerVO;
        }

        // 查询客服信息
        List<TbWecomExternalContactFollowUser> followUsers = followUserMapper.selectList(
            Wrappers.lambdaQuery(TbWecomExternalContactFollowUser.class)
                .select(TbWecomExternalContactFollowUser::getUserId, TbWecomExternalContactFollowUser::getUserName)
                .in(TbWecomExternalContactFollowUser::getUserId, userIds)
        );

        Map<String, String> userIdToNameMap = followUsers.stream()
            .collect(Collectors.toMap(TbWecomExternalContactFollowUser::getUserId,
                TbWecomExternalContactFollowUser::getUserName));

        List<CustomerFollowUserDetailVO> customerFollowUserDetailVOS = BeanUtil.copyToList(tbWecomExternalContactCustomerFollowUsers, CustomerFollowUserDetailVO.class);
        customerFollowUserDetailVOS.forEach(dto -> {
            dto.setUserName(userIdToNameMap.get(dto.getUserId()));
        });

        // 查询标签关系
        List<TbWecomExternalContactCustomerFollowUserTag> tbWecomExternalContactCustomerFollowUserTags = customerFollowUserTagMapper.selectList(Wrappers.lambdaQuery(TbWecomExternalContactCustomerFollowUserTag.class)
            .select(TbWecomExternalContactCustomerFollowUserTag::getUserId,
                TbWecomExternalContactCustomerFollowUserTag::getExternalUserid,
                TbWecomExternalContactCustomerFollowUserTag::getTagId)
            .in(TbWecomExternalContactCustomerFollowUserTag::getUserId, userIds)
            .eq(TbWecomExternalContactCustomerFollowUserTag::getExternalUserid, externalUserid));

        if (!tbWecomExternalContactCustomerFollowUserTags.isEmpty()) {
            // 根据 tagId 获取标签信息
            Set<String> tagIds = tbWecomExternalContactCustomerFollowUserTags.stream()
                .map(TbWecomExternalContactCustomerFollowUserTag::getTagId)
                .collect(Collectors.toSet());

            // 查询标签信息
            List<TbWecomTag> tbWecomTags = tbWecomTagMapper.selectList(Wrappers.lambdaQuery(TbWecomTag.class)
                .in(TbWecomTag::getTagId, tagIds)
            );

            // 获取标签组ID
            Set<String> tagGroupIds = tbWecomTags.stream()
                .map(TbWecomTag::getTagGroupId)
                .collect(Collectors.toSet());

            // 查询标签组信息
            List<TbWecomTagGroup> tbWecomTagGroups = tbWecomTagGroupMapper.selectList(Wrappers.lambdaQuery(TbWecomTagGroup.class)
                .in(TbWecomTagGroup::getGroupId, tagGroupIds)
            );

            // 构建标签组Map
            Map<String, TbWecomTagGroup> tagGroupMap = tbWecomTagGroups.stream()
                .collect(Collectors.toMap(TbWecomTagGroup::getGroupId, Function.identity()));

            // 构建标签Map
            Map<String, TbWecomTag> tagMap = tbWecomTags.stream()
                .collect(Collectors.toMap(TbWecomTag::getTagId, Function.identity()));

            // 按用户ID分组标签关系
            Map<String, List<TbWecomExternalContactCustomerFollowUserTag>> userTagsMap = tbWecomExternalContactCustomerFollowUserTags.stream()
                .collect(Collectors.groupingBy(TbWecomExternalContactCustomerFollowUserTag::getUserId));

            // 为每个客服组装标签信息
            for (CustomerFollowUserDetailVO detailVO : customerFollowUserDetailVOS) {
                List<TbWecomExternalContactCustomerFollowUserTag> userTags = userTagsMap.get(detailVO.getUserId());
                if (userTags != null && !userTags.isEmpty()) {
                    // 按标签组分组标签
                    Map<String, List<CustomerFollowUserTagDetailVO>> tagGroupDetailMap = new HashMap<>();

                    for (TbWecomExternalContactCustomerFollowUserTag userTag : userTags) {
                        TbWecomTag tag = tagMap.get(userTag.getTagId());
                        if (tag != null) {
                            TbWecomTagGroup tagGroup = tagGroupMap.get(tag.getTagGroupId());
                            if (tagGroup != null) {
                                String groupId = tagGroup.getGroupId();
                                tagGroupDetailMap.computeIfAbsent(groupId, k -> new ArrayList<>())
                                    .add(new CustomerFollowUserTagDetailVO(tag.getTagId(), tag.getTagName()));
                            }
                        }
                    }

                    // 构建标签组详情列表
                    List<CustomerFollowUserTagGroupDetailVO> tagGroupDetailVOS = new ArrayList<>();
                    for (Map.Entry<String, List<CustomerFollowUserTagDetailVO>> entry : tagGroupDetailMap.entrySet()) {
                        String groupId = entry.getKey();
                        TbWecomTagGroup tagGroup = tagGroupMap.get(groupId);
                        if (tagGroup != null) {
                            CustomerFollowUserTagGroupDetailVO tagGroupDetailVO = new CustomerFollowUserTagGroupDetailVO();
                            tagGroupDetailVO.setTagGroupId(groupId);
                            tagGroupDetailVO.setTagGroupName(tagGroup.getGroupName());
                            tagGroupDetailVO.setCustomerFollowUserTagVO(entry.getValue());
                            tagGroupDetailVOS.add(tagGroupDetailVO);
                        }
                    }

                    detailVO.setCustomerFollowUserTagGroupVO(tagGroupDetailVOS);
                }
            }
        }

        tbWecomCustomerVO.setCustomerFollowUserDetailVO(customerFollowUserDetailVOS);
        return tbWecomCustomerVO;
    }

    private Map<String, List<CustomerChatGroupVO>> getCustomerChatGroups(Set<String> externalUserIds) {
        // 查询群成员信息
        LambdaQueryWrapper<TbWecomChatGroupMember> wrapper = Wrappers.lambdaQuery(TbWecomChatGroupMember.class)
            .select(TbWecomChatGroupMember::getChatId, TbWecomChatGroupMember::getUserId)
            .in(TbWecomChatGroupMember::getUserId, externalUserIds)
            .eq(TbWecomChatGroupMember::getUserType, 2) // 2-外部联系人
            .eq(TbWecomChatGroupMember::getStatus, 0);  // 0-在群


        List<TbWecomChatGroupMember> tbWecomChatGroupMembers = chatGroupMemberMapper.selectList(wrapper);

        if (CollectionUtils.isEmpty(tbWecomChatGroupMembers)) {
            return Collections.emptyMap();
        }

        // 获取所有群聊ID
        Set<String> chatIds = tbWecomChatGroupMembers.stream()
            .map(TbWecomChatGroupMember::getChatId)
            .collect(Collectors.toSet());

        // 查询群聊信息
        List<TbWecomChatGroup> chatGroups = chatGroupMapper.selectList(
            Wrappers.lambdaQuery(TbWecomChatGroup.class)
                .select(TbWecomChatGroup::getChatId, TbWecomChatGroup::getChatName)
                .in(TbWecomChatGroup::getChatId, chatIds)
        );

        Map<String, String> chatIdToNameMap = chatGroups.stream()
            .collect(Collectors.toMap(TbWecomChatGroup::getChatId, TbWecomChatGroup::getChatName));

        // 按客户分组群聊信息
        Map<String, List<CustomerChatGroupVO>> result = new HashMap<>();
        for (TbWecomChatGroupMember member : tbWecomChatGroupMembers) {
            String externalUserId = member.getUserId();
            String chatId = member.getChatId();
            String chatName = chatIdToNameMap.getOrDefault(chatId, "未知群聊");
            CustomerChatGroupVO chatGroupVO = new CustomerChatGroupVO();
            chatGroupVO.setChatId(chatId);
            chatGroupVO.setChatName(chatName);
            result.computeIfAbsent(externalUserId, k -> new ArrayList<>()).add(chatGroupVO);
        }

        return result;
    }

    private Map<String, List<CustomerFollowUserVO>> getCustomerFollowUsers(Set<String> externalUserIds) {
        // 查询客户跟进关系
        List<TbWecomExternalContactCustomerFollowUser> followRelations = customerFollowUserMapper.selectList(
            Wrappers.lambdaQuery(TbWecomExternalContactCustomerFollowUser.class)
                .in(TbWecomExternalContactCustomerFollowUser::getExternalUserid, externalUserIds)
                .eq(TbWecomExternalContactCustomerFollowUser::getStatus, 0) // 0-未流失
        );

        if (CollectionUtils.isEmpty(followRelations)) {
            return Collections.emptyMap();
        }

        // 获取客服ID
        Set<String> userIds = followRelations.stream()
            .map(TbWecomExternalContactCustomerFollowUser::getUserId)
            .collect(Collectors.toSet());

        // 查询客服信息
        List<TbWecomExternalContactFollowUser> followUsers = followUserMapper.selectList(
            Wrappers.lambdaQuery(TbWecomExternalContactFollowUser.class)
                .select(TbWecomExternalContactFollowUser::getUserId, TbWecomExternalContactFollowUser::getUserName)
                .in(TbWecomExternalContactFollowUser::getUserId, userIds)
        );

        Map<String, String> userIdToNameMap = followUsers.stream()
            .collect(Collectors.toMap(TbWecomExternalContactFollowUser::getUserId,
                TbWecomExternalContactFollowUser::getUserName));

        // 查询标签信息
        Map<FollowUserTagKey, List<CustomerFollowUserTagVO>> tagsMap = getFollowUserTags(externalUserIds, userIds);

        // 组装客服VO数据
        Map<String, List<CustomerFollowUserVO>> result = new HashMap<>();
        for (TbWecomExternalContactCustomerFollowUser relation : followRelations) {
            String externalUserId = relation.getExternalUserid();
            String userId = relation.getUserId();
            String userName = userIdToNameMap.get(userId);
            if (userName != null) {
                CustomerFollowUserVO followUserVO = new CustomerFollowUserVO();
                followUserVO.setUserId(userId);
                followUserVO.setUserName(userName);
                followUserVO.setRemark(relation.getRemark());
                // 设置标签
                FollowUserTagKey key = new FollowUserTagKey(externalUserId, userId);
                List<CustomerFollowUserTagVO> tags = tagsMap.get(key);
                followUserVO.setCustomerFollowUserTagVO(tags != null ? tags : Collections.emptyList());

                result.computeIfAbsent(externalUserId, k -> new ArrayList<>()).add(followUserVO);
            }
        }

        return result;
    }

    private Map<FollowUserTagKey, List<CustomerFollowUserTagVO>> getFollowUserTags(Set<String> externalUserIds, Set<String> userIds) {
        // 1. 先查询客户跟进标签关系
        List<TbWecomExternalContactCustomerFollowUserTag> tags = customerFollowUserTagMapper.selectList(
            Wrappers.lambdaQuery(TbWecomExternalContactCustomerFollowUserTag.class)
                .in(TbWecomExternalContactCustomerFollowUserTag::getExternalUserid, externalUserIds)
                .in(TbWecomExternalContactCustomerFollowUserTag::getUserId, userIds)
        );

        if (CollectionUtils.isEmpty(tags)) {
            return Collections.emptyMap();
        }

        // 2. 提取所有标签ID
        Set<String> tagIds = tags.stream()
            .map(TbWecomExternalContactCustomerFollowUserTag::getTagId)
            .collect(Collectors.toSet());

        // 3. 从 tb_wecom_tag 表查询标签名称
        List<TbWecomTag> wecomTags = tbWecomTagMapper.selectList(
            Wrappers.lambdaQuery(TbWecomTag.class)
                .in(TbWecomTag::getTagId, tagIds)
        );

        // 4. 构建标签ID到标签名称的映射
        Map<String, String> tagIdToNameMap = wecomTags.stream()
            .collect(Collectors.toMap(TbWecomTag::getTagId, TbWecomTag::getTagName));

        // 5. 组装结果
        Map<FollowUserTagKey, List<CustomerFollowUserTagVO>> result = new HashMap<>();
        for (TbWecomExternalContactCustomerFollowUserTag tag : tags) {
            FollowUserTagKey key = new FollowUserTagKey(tag.getExternalUserid(), tag.getUserId());

            CustomerFollowUserTagVO tagVO = new CustomerFollowUserTagVO();
            tagVO.setTagId(tag.getTagId());
            // 从映射中获取标签名称，如果找不到则使用默认值
            tagVO.setTagName(tagIdToNameMap.getOrDefault(tag.getTagId(), "未知标签"));

            result.computeIfAbsent(key, k -> new ArrayList<>()).add(tagVO);
        }

        return result;
    }

    private void assembleCustomerData(List<TbWecomCustomerChatGroupPageVO> customerList,
                                      Map<String, List<CustomerChatGroupVO>> customerChatGroups,
                                      Map<String, List<CustomerFollowUserVO>> customerFollowUsers) {
        for (TbWecomCustomerChatGroupPageVO customer : customerList) {
            String externalUserId = customer.getExternalUserid();

            // 设置群聊信息
            List<CustomerChatGroupVO> chatGroups = customerChatGroups.get(externalUserId);
            customer.setCustomerChatGroupVO(chatGroups != null ? chatGroups : Collections.emptyList());

            // 设置客服信息
            List<CustomerFollowUserVO> followUsers = customerFollowUsers.get(externalUserId);
            customer.setCustomerFollowUserVOS(followUsers != null ? followUsers : Collections.emptyList());
        }
    }
}
